package com.zx1316.javasimpledoudizhu.server;

import com.zx1316.javasimpledoudizhu.misc.Card;
import javafx.application.Platform;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

//这个类处理客户端发来的信息
public class ClientThread extends Thread {
    private final Server server;
    private final Socket socket;
    private final BufferedReader reader;
    private final PrintWriter writer;
    private final String playerName;
    private boolean isReady;

    public ClientThread(Socket socket, String playerName, Server server) {
        try {
            this.socket = socket;
            this.playerName = playerName;
            this.server = server;
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            writer = new PrintWriter(socket.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    @Override
    public void run() {
        while (true) {
            try {
                String message = reader.readLine();
                System.out.println("Server receive " + message + " from id " + getPos() + " name " + server.getGameThread().getPlayerList()[getPos()]);
                if (message.equals("CLOSE")) {
                    deleteClient();
                    socket.close();
                    return;
                }
                for (int i = 0; i < 3; i++) {
                    sendMessage(message + "@" + playerName, i, true);
                }
                String[] splitMessage = message.split("@");
                if (message.equals("READY")) {
                    isReady = true;
                    int i = 0;
                    for (int j = 0; j < 3; j++) {
                        if (Server.getClients()[j] != null && Server.getClients()[j].isReady()) {
                            i++;
                        }
                    }
                    if (i == 3) {
                        if (!server.getGameThread().isInGame()) {
                            Platform.runLater(() -> server.getController().playerConfig.setDisable(true));
                            server.getGameThread().setInGame(true);
                            for (int j = 0; j < 3; j++) {
                                server.getGameThread().getPlayerList()[j] = Server.getClients()[j].getPlayerName();
                            }
                        }
                        synchronized (server.getLock()) {
                            server.getLock().notify();
                        }
                    }
                } else if (message.equals("PASS")) {
                    synchronized (server.getLock()) {
                        server.getLock().notify();
                    }
                } else if (splitMessage[0].equals("CALL")) {
                    server.getGameThread().setPoints(Integer.parseInt(splitMessage[1]));
                    synchronized (server.getLock()) {
                        server.getLock().notify();
                    }
                } else if (splitMessage[0].equals("DISCARD")) {
                    if (splitMessage.length == 5 && splitMessage[1].charAt(1) == splitMessage[2].charAt(1) && splitMessage[2].charAt(1) == splitMessage[3].charAt(1) && splitMessage[3].charAt(1) == splitMessage[4].charAt(1) ||
                            splitMessage.length == 3 && splitMessage[1].equals("JB") && splitMessage[2].equals("JS")) {
                        server.getGameThread().setPoints(server.getGameThread().getPoints() * 2);
                        for (int i = 0; i < 3; i++) {
                            sendMessage("BOMB@true", i, true);
                        }
                    }
                    int pos = getPos();
                    server.getGameThread().getDiscardTimes()[pos]++;
                    for (int i = 1; i < splitMessage.length; i++) {
                        server.getGameThread().getCardsList().get(pos).remove(new Card(splitMessage[i]));
                    }
                    synchronized (server.getLock()) {
                        server.getLock().notify();
                    }
                } else if (splitMessage[0].equals("DOUBLE")) {
                    if (splitMessage[1].equals("true")) {
                        server.getGameThread().getNeedDouble()[getPos()] = 1;
                    } else {
                        server.getGameThread().getNeedDouble()[getPos()] = 0;
                    }
                    int j;
                    for (j = 0; j < 3; j++) {
                        if (server.getGameThread().getNeedDouble()[j] == -1) {
                            break;
                        }
                    }
                    if (j == 3) {
                        synchronized (server.getLock()) {
                            server.getLock().notify();
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                deleteClient();
                return;
            }
        }
    }

    private void deleteClient() {
        int i;
        for (i = 0; i < 3; i++) {
            if (this.equals(Server.getClients()[i])) {
                Server.getClients()[i] = null;
                break;
            }
        }
        if (!server.getGameThread().isInGame()) {
            StringBuilder sb = new StringBuilder("NAME");
            for (int j = 0; j < 3; j++) {
                sb.append("@");
                if (Server.getClients()[j] != null) {
                    sb.append(Server.getClients()[j].getPlayerName());
                } else {
                    sb.append(" ");
                }
            }
            for (int j = 0; j < 3; j++) {
                sendMessage(sb.toString(), j, false);
            }
            int finalI = i;
            Platform.runLater(() -> {
                switch (finalI) {
                    case 0 -> server.getController().name1.setText("");
                    case 1 -> server.getController().name2.setText("");
                    default -> server.getController().name3.setText("");
                }
            });
        } else {
            for (int j = 0; j < 3; j++) {
                sendMessage("DELETE@" + playerName, j, false);
            }
        }
    }

    private int getPos() {
        for (int j = 0; j < 3; j++) {
            if (this.equals(Server.getClients()[j])) {
                return j;
            }
        }
        return -1;
    }

    private void sendMessage(String message, int id, boolean record) {
        if (Server.getClients()[id] != null) {
            System.out.println("Server send " + message + " to id " + id + " name " + server.getGameThread().getPlayerList()[id]);
            Server.getClients()[id].getWriter().println(message);
            Server.getClients()[id].getWriter().flush();
        }
        if (record) {
            server.getGameThread().getRecords().get(id).add(message);
        }
    }

    public PrintWriter getWriter() {
        return writer;
    }

    public Socket getSocket() {
        return socket;
    }

    public String getPlayerName() {
        return playerName;
    }

    public boolean isReady() {
        return isReady;
    }

    public void setReady(boolean b) {
        this.isReady = b;
    }
}
